/**
 * snow_bros/snow_bros
 * 洛克人选关画面
 * 
 * @author Zdream
 * @since Aurora 0.4.0
 */

import soundFactory from './sound';

function create(context, key) {
	switch (key) {
		case 'main': return createMain(context);
		case 'sound': return createSoundPromise(context);
		default: return null;
	}
}

function createMain(context) {
  return {
    template : context.template,
    data : function () {
      let d = {
        status : null,
        dirty : false,
        frames : [],

        frameIndexs : [
          [0, 1, 2],
          [7, null, 3],
          [6, 5, 4],
        ],

        options : [
          {avatar : 'null', name : '空', defName : ''},
        ],
        optionMap : {
          'null' : ''
        },
      };

      for (let i = 0; i < 8; i++) {
        d.frames.push({
          avatar : '',
          title : '',
          enable : false,
        });
      }

      return d;
    },
    props : {
      sid : String,
    },
    methods : {
      // 1. 基础部分
      btnAnimeOpenWait : function () { // 到启动动画前
        context.sendCommand(this.sid, 'updateAnime', {open : 2});
      },
      btnAnimeOpenBegin : function () { // 到启动动画
        context.sendCommand(this.sid, 'updateAnime', {open : 1});
      },

      btnValueReset : function () {
        this.dirty = false;
        this.buildData();
      },
      btnValueSubmit : function () {
        let frames = JSON.parse(JSON.stringify(this.frames));
        context.sendCommand(this.sid, 'updateFrame', { frames });
        this.dirty = false;
      },
      btnDefaultName : function (index) {
        const avatar = this.frames[index].avatar;
        this.dirty = true;

        this.frames[index].title = (this.optionMap[avatar]) ? this.optionMap[avatar] : '';
      },
      btnSelect : function (index) {
        context.sendCommand(this.sid, 'changeCursor', {cursor : index});
      },
      /**
       * 每个框随机头像，或者 index=null 为全随机. 随机不能选到 null
       * @param {number} index 
       */
      btnRandomAvatar : function (index) {
        this.dirty = true;
        const avatarMap = this.optionMap;

        if (index != null) {
          // 单个框随机
          // 先将已经选的头像理出来
          const already = {};
          this.frames.forEach((frame, index0) => {
            if (index != index0)
              already[frame.avatar] = true;
          });
          let array = this.options
              .map((item) => item.avatar)
              .filter((item) => already[item] == null && item != 'null');
          if (array.length === 0) {
            array = this.options
                .map((item) => item.avatar)
                .filter((item) => item != 'null');
          }
          if (array.length === 0) { // 还等于 0 说明 option 没被加载
            return;
          }

          // console.log(array, already);
          let frame = this.frames[index];
          let oldAvatar = frame.avatar;
          let isDefName = frame.title === avatarMap[oldAvatar];

          let newAvatar = frame.avatar = array[parseInt(Math.random() * array.length)];
          if (isDefName) {
            frame.title = avatarMap[newAvatar];
          }
        } else {
          let array = this.options
              .map((item) => item.avatar)
              .filter((item) => item != 'null');
          if (array.length === 0) { // 等于 0 说明 option 没被加载
            return;
          }
          // 如果 array.length <= this.frames.length 满足, 就放回抽取
          let enough = array.length <= this.frames.length;

          this.frames.forEach((frame) => {
            // 原来的头像
            let oldAvatar = frame.avatar;
            let isDefName = frame.title === avatarMap[oldAvatar];

            let newAvatar = frame.avatar = array[parseInt(Math.random() * array.length)];
            if (isDefName) {
              frame.title = avatarMap[newAvatar];
            }
            if (!enough) {
              array = array.filter((item) => item != newAvatar);
            }
          });
        }
      },
      btnRoundBegin : function () {
        context.sendCommand(this.sid, 'startRound');
      },
      btnRoundEnd : function () {
        context.sendCommand(this.sid, 'endRound');
      },

      onValueChange : function (index, key, event) {
        this.dirty = true;
        const frame = this.frames[index];
        switch (key) {
          case 'enable': {
            frame[key] = event.target.checked;
          } break;
          case 'title': {
            frame[key] = event.target.value;
          } break;
          case 'avatar': {
            let oldAvatar = frame.avatar;
            let isDefName = frame.title === this.optionMap[oldAvatar];

            let newAvatar = frame.avatar = event;
            // 如果名字是默认名, 则名称也会改
            if (isDefName) {
              frame.title = this.optionMap[newAvatar];
            }
          } break;
          default :
            console.log(index, key, event);
        }
      },
      buildData : function () {
        if (this.status && this.status.data) {
          this.status.data.frames.forEach((frame, index) => {
            let dest = this.frames[index];
            dest.enable = frame.enable;
            dest.avatar = frame.avatar;
            dest.title = frame.title;
          });
        }
      },
      loadFrameMeta : function () {
        fetch('/aurora-res/rockman/img/rmframes-meta.json')
          .then(res => res.json())
          .then(data => {
            this.options = data.options;
            data.options.forEach((option) => {
              this.optionMap[option.avatar] = option.defName;
            })
          });
      },

      // 监听事件部分
      onScreenUpdated : function () {
        this.status = context.getStatus(this.sid);
        if (!this.dirty) {
          this.buildData();
        }
      },
    },
    mounted : function () {
      this.onScreenUpdated();
      this.loadFrameMeta();
      
      context.getBus().$on('screen-status-sync-all', this.onScreenUpdated);
      context.getBus().$on('screen-updated', this.onScreenUpdated);
      context.getBus().$on('screen-destroyed', this.onScreenUpdated);
    },
    destroyed : function () {
      context.getBus().$off('screen-status-sync-all', this.onScreenUpdated);
      context.getBus().$off('screen-updated', this.onScreenUpdated);
      context.getBus().$off('screen-destroyed', this.onScreenUpdated);
    }
  }
}

function createSoundPromise(context) {
  return context.fetchHtmlScript('monitor/sound.html').then(html => {
		return soundFactory(context, html);
	});
}

export default {
	factory : create,
	tabs : [{
		key : 'sound',
		name : '音量',
		icon : 'sound'
	}]
};
